之前总是习惯编写面向过程的程序,没有面向对象的思维,用这个文本查询程序作为一个面向对象的小练习.
用面向过程的方式很快就写完了,用面向对象实现的时候还是遇到不少小问题.
这个小程序实现了”打印文本中存在某单词所在的行”的功能:
1 2 3 4 5
| root@yifei: ./textquery data.txt hello 查询到3个hello. (line 2) ni hao a hello (line 33) hello daming (line 40 hello world.
|
面向过程实现文本查询程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #include <iostream> #include <fstream> #include <sstream> #include <map> #include <string> #include <list> #include <forward_list> #include <deque> #include <cstdio> #include <vector> #include <algorithm> #include <numeric> #include <ctime> #include <iterator> #include <utility> #include <memory>
using namespace std;
bool judgefilename(string filename){ string tail=".txt"; if(filename.compare(filename.size()-tail.size(),tail.size(),tail)==0){ return false; }else{ cout<<"sorry,我只接受txt文件."<<endl; return true; } }
bool hasTextFromLine(string line,string querytext){ if(line.find(querytext,0)!=string::npos){ return true; }else{ return false; } }
void printResult(map<int,string> &result,string querytext){ if(result.size()==0){ cout<<"查询到0个"<<querytext<<"."<<endl; return ; } cout<<"查询到"<<result.size()<<"个"<<querytext<<endl; for(auto a:result){ cout<<" (line "; cout<<a.first<<") "<<a.second<<endl; } }
int main(int argc,char *argv[]){
map<int,string> misfile; map<int,string> misresult;
if(argc!=3){ cout<<"格式: <textquery> <filename> <text> ,请重新输入!"<<endl; return -1; } string filename(argv[1]); string text(argv[2]); if(text.size()>100||judgefilename(filename)){ cout<<"参数错误! 请重新输入."<<endl; return -2; }
ifstream is1(filename); string tmp; int linefile=1,lineresult=1; while(getline(is1,tmp)){ misfile.insert({linefile,tmp}); linefile++; if(hasTextFromLine(tmp,text)){ misresult.insert({lineresult,tmp}); lineresult++; } }
printResult(misresult,text); return 0; }
|
面向对象实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| #include <iostream> #include <fstream> #include <sstream> #include <map> #include <string> #include <list> #include <forward_list> #include <deque> #include <cstdio> #include <vector> #include <algorithm> #include <numeric> #include <ctime> #include <iterator> #include <utility> #include <memory> #include "TransactionProcess.h" #include "QueryResult.h" #include "TextQuery.h"
using namespace std;
int main(int argc,char *argv[]){ TransactionProcess tranpro1(argc,argv); if(tranpro1.judgeArg()==false) return -1;
shared_ptr<map<int,string>> smis=make_shared<map<int,string>>(); TextQuery tq(string(argv[1]),smis); tq.textInput(); vector<int> vitmp=tq.returnResult(argv[2]); QueryResult qr(argv[2],tq.returnFile(),vitmp);
printResult(qr);
return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| #ifndef TRAN_PROC #define TRAN_PROC #include <iostream> using namespace std;
class TransactionProcess{ private: int argc; char *argv[5]; public: TransactionProcess()=default; TransactionProcess(int argc1,char *argv1[]); bool judgeArg(); bool judgefilename(string filename); };
TransactionProcess::TransactionProcess(int argc1,char *argv1[]){ argc=argc1; for(int i=0;i<argc1;i++){ argv[i]=argv1[i]; } }
bool TransactionProcess::judgeArg(){ if(argc!=3){ cout<<"格式: <textquery> <filename> <text> ,请重新输入!"<<endl; return false; } string filename(argv[1]); string text(argv[2]); if(text.size()>100||judgefilename(filename)){ cout<<"参数错误! 请重新输入."<<endl; return false; } return true; }
bool TransactionProcess::judgefilename(string filename){ string tail=".txt"; if(filename.compare(filename.size()-tail.size(),tail.size(),tail)==0){ return false; }else{ cout<<"sorry,我只接受txt文件."<<endl; return true; } }
#endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| #ifndef TEXTQUERY #define TEXTQUERY #include <iostream> #include <memory> #include <vector> #include <string> #include <map> #include <fstream>
using namespace std;
class QueryResult;
class TextQuery{ private: shared_ptr<map<int,string>> mis_ptr; string textq; public: TextQuery()=default; TextQuery(string str,shared_ptr<map<int,string>> ptr) : textq(str), mis_ptr(ptr) {}
void textInput(); shared_ptr<map<int,string>> returnFile(); vector<int> returnResult(string querytxt); };
void TextQuery::textInput(){ ifstream fnameis(textq); string tmp; int linefile=1; while(getline(fnameis,tmp)){ mis_ptr->insert({linefile,tmp}); linefile++; } }
shared_ptr<map<int,string>> TextQuery::returnFile(){ return mis_ptr; }
vector<int> TextQuery::returnResult(string querytxt){ vector<int> vi1; for(auto a:*mis_ptr){ if(a.second.find(querytxt)!=string::npos){ vi1.push_back(a.first); } } return vi1; }
#endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #ifndef QUERYRESULT #define QUERYRESULT #include <iostream> #include <string> #include <vector> #include <memory> #include <map> using namespace std;
class QueryResult{ private: string querytext; shared_ptr<map<int,string>> misres_ptr; vector<int> vires; public: QueryResult()=default; QueryResult(string qt,shared_ptr<map<int,string>> misptr,vector<int> vi) : querytext(qt),misres_ptr(misptr),vires(vi) {} public: friend void printResult(QueryResult &qr1); };
void printResult(QueryResult &qr1){ if(qr1.vires.size()==0){ cout<<"查询到0个"<<qr1.querytext<<"."<<endl; return ; } cout<<"查询到"<<qr1.vires.size()<<"个"<<qr1.querytext<<endl; for(auto a:qr1.vires){ cout<<" (line "; cout<<a<<") "<<(*qr1.misres_ptr)[a]<<endl; } } #endif
|
总结
- 头文件包含顺序
当ClassA.h中需要创建ClassB.h中的类的时候,如果a.cpp中需要包含以上两个头文件,那么在a.cpp中需要首先引用ClassB.h,然后再引用ClassA.h.
- 友元函数
1.友元函数可以访问类中的私有成员和其他数据,但是访问不可直接使用数据成员,需要通过对对象进行引用。
2.友元函数在调用上同一般函数一样,不必通过对对象进行引用。
3.一个类中的成员函数可以是另外一个类的友元函数,而且一个函数可以是多个类的友元函数。
4.类中通过使用关键字friend 来修饰友元函数,但该函数并不是类的成员函数,其声明可以放在类的私有部分,也可放在共有部分。友元函数的定义在类体外实现,不需要加类限定。
- 当不同的类可以共用数据时,可以利用shared_ptr智能指针来共享数据.
- 查找一个string中是否包含另一个string
1 2 3 4 5
| if(stra.find(strb)!=string::npos){//该函数返回该串的位置 cout<<"存在该串"<<endl; }else{ cout<<"不存在"<<endl; }
|
欢迎与我分享你的看法。
转载请注明出处:http://taowusheng.cn/